﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Drawing;
using System.Windows.Forms;

namespace GMusicBox
{
    [System.ComponentModel.DefaultEvent("Click")]
    public class ButtonX : PictureBox
    {
        public ButtonX()
        {
            this.BackgroundImageLayout = ImageLayout.Center;
        }

        Image normalImage = null;

        public Image NormalImage
        {
            get { return normalImage; }
            set
            {
                normalImage = value;
                if (this.Image == null || (this.Image != EnterImage && this.Image != DowningImage)) this.Image = normalImage;
            }
        }

        public Image EnterImage { get; set; }
        public Image DowningImage { get; set; }

        protected override void OnMouseEnter(EventArgs e)
        {
            this.Image = EnterImage;
            base.OnMouseEnter(e);
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            this.Image = NormalImage;
            base.OnMouseLeave(e);
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            this.Image = DowningImage;
            base.OnMouseDown(e);
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            this.Image = EnterImage;
            base.OnMouseUp(e);
        }
    }

    [System.ComponentModel.DefaultEvent("Click")]
    public class GButton : System.Windows.Forms.UserControl
    {
        Bitmap fore;
        protected PictureButtonRegion region = new PictureButtonRegion();
        Bitmap normal, enter, down, dis, foc;
        protected bool downing, moving;

        public GButton()
        {
            this.DoubleBuffered = true;
            InitControl();
        }

        protected override void OnGotFocus(EventArgs e)
        {
            base.OnGotFocus(e);
            this.Invalidate();
        }

        protected override void OnLostFocus(EventArgs e)
        {
            base.OnLostFocus(e);
            this.Invalidate();
        }

        protected override void OnEnabledChanged(EventArgs e)
        {
            if (this.Enabled) this.ForeColor = Color.Black;
            else this.ForeColor = Color.Gray;
            base.OnEnabledChanged(e);
        }

        protected virtual void InitControl()
        {
            SetToolBarImage(res.ButtonGoogle, 5, Direction.Horizontal);
            region = new PictureButtonRegion();
            region.NormalImageRegion = new System.Drawing.Rectangle(3, 3, 17, 17);
            region.EnterImageRegion = new Rectangle(3, 3, 17, 17);
            region.DowningImageRegion = new Rectangle(3, 3, 17, 17);
            region.FocusedImageRegion = new Rectangle(3, 3, 17, 17);
            region.DisabledImageRegion = new Rectangle(3, 3, 17, 17);
        }

        public void SetToolBarImage(Bitmap bitmap, int itemcount, Direction Dir)
        {
            Bitmap b = new Bitmap(Dir == Direction.Horizontal ? bitmap.Width / itemcount : bitmap.Width, Dir == Direction.Vertical ? bitmap.Height / itemcount : bitmap.Height);
            Graphics g = Graphics.FromImage(b);
            int Xoffset = Dir == Direction.Horizontal ? bitmap.Width / itemcount : 0;
            int Yoffset = Dir == Direction.Vertical ? bitmap.Height / itemcount : 0;

            for (int i = 0; i < 5; i++)
            {
                b = new Bitmap(Dir == Direction.Horizontal ? bitmap.Width / itemcount : bitmap.Width, Dir == Direction.Vertical ? bitmap.Height / itemcount : bitmap.Height);
                g = Graphics.FromImage(b);
                g.DrawImage(bitmap, new Rectangle(0, 0, b.Width, b.Height), new Rectangle(i * Xoffset, i * Yoffset, b.Width, b.Height), GraphicsUnit.Pixel);
                if (i == 0) normal = b;
                else if (i == 1) EnterImage = new Bitmap(b);
                else if (i == 2) DowningImage = new Bitmap(b);
                else if (i == 3) FocusedImage = new Bitmap(b);
                else if (i == 4) DisabledImage = new Bitmap(b);
            }

            g.Dispose();
            b.Dispose();
        }

        private Bitmap GetResizedImage(Bitmap from, Rectangle region)
        {
            //try
            //{
            Bitmap b = new Bitmap(this.Width, this.Height);
            Graphics g = Graphics.FromImage(b);
            g.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
            g.DrawImage(from,
                new Rectangle(0, 0, region.Left, region.Top),
                new Rectangle(0, 0, region.Left, region.Top), GraphicsUnit.Pixel);
            g.DrawImage(from,
                new Rectangle(0, region.Top, region.Left, this.Height - (from.Height - region.Height)),
                new Rectangle(0, region.Top, region.Left, region.Height), GraphicsUnit.Pixel);
            g.DrawImage(from,
                new Rectangle(0, this.Height - (from.Height - region.Bottom), region.Left, region.Top),
                new Rectangle(0, region.Bottom, region.Left, region.Top), GraphicsUnit.Pixel);
            g.DrawImage(from,
                new Rectangle(region.Left, 0, this.Width - (from.Width - region.Width), region.Top),
                new Rectangle(region.Left, 0, region.Width, region.Top), GraphicsUnit.Pixel);
            g.DrawImage(from,
                new Rectangle(region.Left, region.Top, this.Width - (from.Width - region.Width), this.Height - (from.Height - region.Height)), region, GraphicsUnit.Pixel);
            g.DrawImage(from,
                new Rectangle(region.Left, this.Height - (from.Height - region.Bottom), this.Width - (from.Width - region.Width), region.Top),
                new Rectangle(region.Left, region.Bottom, region.Width, from.Height - region.Bottom), GraphicsUnit.Pixel);
            g.DrawImage(from,
                new Rectangle(this.Width - (from.Width - region.Right), 0, region.Left, region.Top),
                new Rectangle(region.Right, 0, region.Left, region.Top), GraphicsUnit.Pixel);
            g.DrawImage(from,
                new Rectangle(this.Width - (from.Width - region.Right), region.Top, from.Width - region.Right, this.Height - (from.Height - region.Height)),
                new Rectangle(region.Right, region.Top, from.Width - region.Right, region.Height), GraphicsUnit.Pixel);
            g.DrawImage(from,
                new Rectangle(this.Width - (from.Width - region.Right), this.Height - (from.Height - region.Bottom), region.Left, region.Top),
                new Rectangle(region.Right, region.Bottom, region.Left, region.Top), GraphicsUnit.Pixel);
            g.Dispose();
            return b;
            //}
            //catch { return null; }
        }

        public Point TextOffset { get; set; }
        public bool ShowArrow { get; set; }

        public Bitmap Image
        {
            get { return fore; }
            set
            {
                fore = value;
                this.Invalidate();
            }
        }

        private Bitmap NormalImage
        {
            get { return GetResizedImage(normal, region.NormalImageRegion); }
        }

        private Bitmap EnterImage
        {
            get { return GetResizedImage(enter, region.EnterImageRegion); }
            set
            {
                enter = value;
                this.Invalidate();
            }
        }

        private Bitmap DowningImage
        {
            get { return GetResizedImage(down, region.DowningImageRegion); }
            set
            {
                down = value;
                this.Invalidate();
            }
        }

        private Bitmap DisabledImage
        {
            get { return GetResizedImage(dis, region.DisabledImageRegion); }
            set
            {
                dis = value;
                this.Invalidate();
            }
        }

        private Bitmap FocusedImage
        {
            get { return GetResizedImage(foc, region.FocusedImageRegion); }
            set
            {
                foc = value;
                this.Invalidate();
            }
        }

        protected override void OnPaint(PaintEventArgs pe)
        {
            base.OnPaint(pe);
            pe.Graphics.FillRectangle(new SolidBrush(this.BackColor), this.Bounds);
            Graphics g = pe.Graphics;

            if (this.Enabled)
            {
                if (downing) g.DrawImage(DowningImage, 0, 0);
                else if (moving) g.DrawImage(EnterImage, 0, 0);
                else
                {
                    if (FocusedImage != null && this.Focused) g.DrawImage(FocusedImage, 0, 0);
                    else g.DrawImage(NormalImage, 0, 0);
                }
            }
            else g.DrawImage(DisabledImage, 0, 0);

            if (fore != null)
                g.DrawImage(fore, new Rectangle(this.Width / 2 - fore.Width / 2, this.Height / 2 - fore.Height / 2, fore.Width, fore.Height));

            Size s = TextRenderer.MeasureText(this.Text, this.Font);
            pe.Graphics.DrawString(this.Text, this.Font, new SolidBrush(this.ForeColor), new PointF(this.Width / 2 - s.Width / 2 + TextOffset.X, this.Height / 2 - s.Height / 2 + TextOffset.Y));
            if (ShowArrow) pe.Graphics.DrawImage(res.addtoarrow, this.Width - 12, this.Height / 2 - res.addtoarrow.Height / 2 + 1);
        }

        protected override void OnMouseEnter(EventArgs e)
        {
            base.OnMouseEnter(e);
            moving = true;
            Invalidate();
        }

        protected override void OnMouseLeave(EventArgs e)
        {
            base.OnMouseLeave(e);
            moving = false;
            Invalidate();
        }

        protected override void OnMouseDown(MouseEventArgs e)
        {
            base.OnMouseDown(e);
            downing = true;
            Invalidate();
        }

        protected override void OnMouseUp(MouseEventArgs e)
        {
            base.OnMouseUp(e);
            downing = false;
            Invalidate();
        }

        protected override void OnTextChanged(EventArgs e)
        {
            base.OnTextChanged(e);
            this.Invalidate();
        }
    }

    public class PictureButtonRegion
    {
        Rectangle nr, dor, er;

        public Rectangle NormalImageRegion
        {
            get { return nr; }
            set { nr = value; }
        }

        public Rectangle DowningImageRegion
        {
            get { return dor; }
            set { dor = value; }
        }

        public Rectangle EnterImageRegion
        {
            get { return er; }
            set { er = value; }
        }

        public Rectangle FocusedImageRegion { get; set; }
        public Rectangle DisabledImageRegion { get; set; }
    }

    public enum Direction
    {
        Horizontal, Vertical
    }

    public enum MouseState
    {
        None, Downing, Entered
    }
}
